package cn.virens.server.tio_http;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.http.common.HttpConfig;
import org.tio.http.server.HttpServerStarter;
import org.tio.http.server.handler.DefaultHttpRequestHandler;
import org.tio.http.server.mvc.Routes;
import org.tio.utils.thread.pool.DefaultThreadFactory;
import org.tio.utils.thread.pool.SynThreadPoolExecutor;

import cn.virens.app.AppConfig;
import cn.virens.app.cmpt.Component;

/**
 * HTTP 服务管理器
 * 
 * @作者   : virens
 * @创建时间 :2018年1月8日 上午9:55:12
 */
public class WebServerManagerImpl implements WebServerManager, Component {
	protected static Logger logger = LoggerFactory.getLogger(WebServerManagerImpl.class);

	private static final long KEEP_ALIVE_TIME = 90L;
	private static final int CORE_POOL_SIZE = 2;
	private static final int MAX_POOL_SIZE = 4;

	private Routes routes;
	private HttpConfig httpConfig;
	private DefaultHttpRequestHandler requestHandler;

	private ThreadPoolExecutor groupExecutor;
	private SynThreadPoolExecutor tioExecutor;
	private HttpServerStarter webServerStarter;

	@Override
	public void initialize(AppConfig config) throws Exception {
		// TIO 执行队列
		LinkedBlockingQueue<Runnable> tioQueue = new LinkedBlockingQueue<>();
		DefaultThreadFactory threadFactory0 = DefaultThreadFactory.getInstance("tio-web", Thread.NORM_PRIORITY);
		this.tioExecutor = new SynThreadPoolExecutor(CORE_POOL_SIZE, CORE_POOL_SIZE, KEEP_ALIVE_TIME, tioQueue, threadFactory0, "tio-web");

		// TIO 分组队列
		LinkedBlockingQueue<Runnable> groupQueue = new LinkedBlockingQueue<>();
		DefaultThreadFactory threadFactory1 = DefaultThreadFactory.getInstance("tio-web-group", Thread.NORM_PRIORITY);
		this.groupExecutor = new ThreadPoolExecutor(MAX_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, groupQueue, threadFactory1);

		// HTTP 配置
		this.httpConfig = new HttpConfig(config.getInteger("tio.http.port"), false);
		this.httpConfig.setWelcomeFile(config.getString("tio.http.welcome.file"));
		this.httpConfig.setServerInfo(config.getString("tio.http.server.info"));
		this.httpConfig.setPageRoot(config.getString("tio.http.page.root"));
		this.httpConfig.setPage404(config.getString("tio.http.page.404"));
		this.httpConfig.setPage500(config.getString("tio.http.page.500"));
		this.httpConfig.setCharset(config.getString("tio.http.charset"));

		// 路由&处理器
		this.routes = new Routes(new String[] { "cn.virens.http.controller" });
		this.requestHandler = new DefaultHttpRequestHandler(httpConfig, routes);

		// 服务初始化
		this.webServerStarter = new HttpServerStarter(httpConfig, requestHandler, tioExecutor, groupExecutor);
		this.webServerStarter.start();
	}

	@Override
	public void destroy() throws Exception {
		this.webServerStarter.stop();
	}
}
